package com.googlecode.connectlet.crypto.digest;

public abstract class HmacStream extends DigestStream {
	private static final long serialVersionUID = 1L;

	protected abstract DigestStream getDigestStream();

	private byte[] key;
	private byte[] inPad = new byte[64];
	private byte[] outPad = new byte[64];
	private DigestStream streamIn;
	private DigestStream streamOut;

	protected HmacStream(byte[] key) {
		this.key = key;
		reset();
	}

	@Override
	public void reset() {
		int i = 0;
		for (; i < key.length; i ++) {
			inPad[i] = (byte) (key[i] ^ 0x36);
			outPad[i] = (byte) (key[i] ^ 0x5c);
		}
		for (; i < 64; i ++) {
			inPad[i] = 0x36;
			outPad[i] = 0x5c;
		}
		streamIn = getDigestStream();
		streamIn.write(inPad);
		streamOut = getDigestStream();
	}

	@Override
	public void write(byte[] b, int off, int len) {
		streamIn.write(b, off, len);
	}

	@Override
	public byte[] digest() {
		streamOut.reset();
		streamOut.write(outPad);
		streamOut.write(streamIn.digest());
		return streamOut.digest();
	}
}